package org.artifact.core.plugin.storage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.Setting;
import org.artifact.core.db.BaseDao;
import org.artifact.core.lang.IPlugin;
import org.artifact.core.lang.IServer;
import org.artifact.core.lang.MapPlus;
import org.artifact.core.plugin.ioc.IocPlugin;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 数据库落地插件
 * @author apple
 *
 */
public class StoragePlugin implements IPlugin {
	
	static final Log log = LogFactory.get(StoragePlugin.class);
	
	private Set<BaseDao<?>> daos = new HashSet<>();

	private StoragePluginConfig config;

	public StoragePlugin() {
		Map config = IServer.me().getContext().getConfig();
		Map storage = MapPlus.get("plugins.storage",config);
		this.config = BeanUtil.mapToBean(storage,StoragePluginConfig.class,false);
	}

	public StoragePlugin(StoragePluginConfig config) {
		this.config = config;
	}

	@Override
	public boolean start() {
		try {
			// 扫描包
			scanPackage();
			// 检查表
			existsTable();
			// 开启定时
			CronUtil.schedule(config.getCrontab(), new Task() {
			    @Override
			    public void execute() {
			    	finishAll();
			    }
			});

			// 支持秒级别定时任务
//			CronUtil.setMatchSecond(true);
			CronUtil.start();
			
			
			return true;
		} catch (Exception e) {
			log.error(e);
		}
		return false;
	}

	@Override
	public boolean stop() {
		// 停止定时
		CronUtil.stop();
		
		for (BaseDao<?> baseDao : daos) {
			baseDao.shutdown();
		}
		return true;
	}

	/**
	 * 检查表
	 */
	private void existsTable() {
		log.info("-> existsTable");
		for (BaseDao<?> baseDao : daos) {
			if (!baseDao.existsTable()) {
				baseDao.createTable();
			}
		}
	}
	
	
	public void finishAll() {
		log.info("-> finishAll");
		for (BaseDao<?> baseDao : daos) {
			baseDao.finishAll();
		}
	}

	/**
	 * 扫描DAO
	 */
	private void scanPackage(){
		Set<Class<?>> clazzs = ClassUtil.scanPackageBySuper(config.getScanPackage(), BaseDao.class);
		for (Class<?> clazz : clazzs) {
			if(ClassUtil.isNormalClass(clazz)) {
				BaseDao<?> baseDao = (BaseDao<?>) IServer.me().getPlugins().getIPlugin(IocPlugin.class).getService(clazz);
				daos.add(baseDao);
			}
		}
	}
}
